import {
  Component,
  OnInit,
  OnDestroy,
  OnChanges,
  AfterViewInit,
  Compiler,
  ViewChild,
  ViewContainerRef,
  ComponentRef
} from '@angular/core';

// import { RuntimeCompiler } from "@angular/compiler";

import { CmModalService, ModalParams } from "./modal.service";
import { Observable } from 'rxjs/Observable';
import { Observer } from 'rxjs/Observer';
import { ModalModule, getDynamicModalModule } from "./../modal-module/modal.module";

import "./../shared/rxjs-operators";

const CM_MODAL = "cm-modal-instance";

@Component({

  selector: 'cm-modal',
  template: `<div #modalContainer></div>`,
  styles: [
    `
      cm-modal {
        position: fixed;
        background-color: rgba(0,0,0,0.3);
      }
    `
  ]
})
export class CmModalComponent implements AfterViewInit {

  @ViewChild("modalContainer", { read: ViewContainerRef })
  protected modalContainer: ViewContainerRef;

  constructor(
    private compiler: Compiler,
    private modalService: CmModalService,
    // private runtimeCompiler: RuntimeCompiler
  ) { }

  /**
   * 创建
   * 
   * @param {ModalParams} params
   * @returns
   * 
   * @memberOf CmModalContainerComponent
   */
  appendModalInstance(params: ModalParams) {
    console.debug("APPEND: ", params);
    let factory;
    // console.debug("Append Modal: ", params);
    return Observable
      .create((observer: Observer<any>) => {
        let subed = true;
        this
          .compiler
          .compileModuleAndAllComponentsAsync(params.isDynamic ?
            getDynamicModalModule(params.templateUrl, params.moduleId) : ModalModule
          )
          .then(data => {
            if (subed) {
              observer.next(data);
              observer.complete();
            }
          })
          .catch(err => {
            if (subed) {
              observer.error(err)
            }
          });
        return () => subed = false;
      })
      .take(1)
      .map(moduleWithFactories => {
        // console.debug("ModalFactories: ", moduleWithFactories)
        return moduleWithFactories
          .componentFactories
          .filter(factory => params.isDynamic ? true : factory.selector === CM_MODAL)
          .reduce(first => first);
      })
      .subscribe(factory => {
        let componentRef = this.modalContainer.createComponent(factory);
        (componentRef.instance as any).params = params;
        for (let i in params) {
          (componentRef.instance as any)[i] = params[i];
        }
        params.closeObserver.subscribe(data => {
          componentRef.destroy();
          componentRef = undefined;
        });
      });
  }


  ngAfterViewInit() {
    this
      .modalService
      .toCreate
      .subscribe(modalParams => this.appendModalInstance(modalParams));
  }

}